
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/power.h>
#include <Wire.h>
#include <DS3231.h>
#include <Fat16.h>
#include <Fat16util.h>
#include <Flash.h>
#include "Battery.h"


// ----------- DEFINES ----------------------

//The following code is taken from sleep.h as Arduino Software v22 (avrgcc) in w32 does not have the latest sleep.h file
#define sleep_bod_disable() \
{ \
  uint8_t tempreg; \
  __asm__ __volatile__("in %[tempreg], %[mcucr]" "\n\t" \
                       "ori %[tempreg], %[bods_bodse]" "\n\t" \
                       "out %[mcucr], %[tempreg]" "\n\t" \
                       "andi %[tempreg], %[not_bodse]" "\n\t" \
                       "out %[mcucr], %[tempreg]" \
                       : [tempreg] "=&d" (tempreg) \
                       : [mcucr] "I" _SFR_IO_ADDR(MCUCR), \
                         [bods_bodse] "i" (_BV(BODS) | _BV(BODSE)), \
                         [not_bodse] "i" (~_BV(BODSE))); \
}


//OJO, el pin D2 se usa para controlar la interrupcion 0 del RTC. Si lo usamos nosotros, en lugar de 
// saltar la interrupción cuando manda el RCT, salta cuando toqueteemos nosotros los niveles en el pin D2

#define FLOAT_SWITCH_D_PIN       3
#define SD_CARD_POWER_D_PIN      4
#define POWER_LED_D_PIN          5
#define DRY_LED_D_PIN            6

// ------ pines analógicos
#define CHARGE_STATUS_A_PIN   6     
#define BATTERY_LEVEL_A_PIN   7     


// --------------------------------------------------------

#define SWITCH_OPEN  LOW
#define SWITCH_CLOSED HIGH


#define SERIAL_BAUDRATE   57600
#define SLEEP_TIME_LONG        30      //secs
#define SLEEP_TIME_SHORT       8      //secs
#define DEBOUNCE_TIME          500     //msecs


#define DEBUG   //para poner/quitar salida datos por puerto serie

#ifdef DEBUG
  #define DEBUG_PRINT(x)  Serial << (x)
  #define DEBUG_PRINT2(x, y)  Serial.print (x, y)
#else
  #define DEBUG_PRINT(x)
  #define DEBUG_PRINT2(x, y)
#endif


// --------------------------------------------------------


class Helper
{
  public: 
    // this function will return the number of bytes currently free in RAM
    // written by David A. Mellis
    // based on code by Rob Faludi http://www.faludi.com

    static int availableMemory()
    {
      int size = 1024; // Use 2048 with ATmega328
      byte *buf;
    
      while ((buf = (byte *) malloc(--size)) == NULL);
      free(buf);
      return size;
    }
  
  
    static String timeToStr(DateTime dt)
    {
      String str = String(dt.year()) + "/";
      addWithLeadingZero(str, dt.month());
      str += "/";
      addWithLeadingZero(str, dt.date());
      str += " ";
      addWithLeadingZero(str, dt.hour());
      str+= ":";
      addWithLeadingZero(str, dt.minute());
      str+= ":";
      addWithLeadingZero(str, dt.second());
      return str;
    }
  
    static void addWithLeadingZero(String& str, int number)
    {
       if (number < 10)
        str += "0";
       str += String(number);
    }

};



// ----- VARIABLES GLOBALES ---------------------------

DS3231 RTC; //Create RTC object for DS3231 RTC come Temp Sensor 
static DateTime interruptTime;

char fileName[] = "Data.log"; //OJO, MÁX 8+3 CARACTERES


int switchStatus = SWITCH_CLOSED; 
Battery battery;

int sleepTime = SLEEP_TIME_LONG;



